package com.film.common.utils;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.film.common.core.domain.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.Base64;

/**
 * 图片上传工具类
 * 支持多种上传方式：PicGo、Imgbb、腾讯COS
 */
@Slf4j
@Component
public class ImageUploadUtil {

    private final TencentCosUtil tencentCosUtil;

    private static final String IMGBB_API_KEY = "3b3c66a59906ea95a3e6d278785c2297";
    private static final String IMGBB_UPLOAD_URL = "https://api.imgbb.com/1/upload?key=" + IMGBB_API_KEY;

    private static final String PICGO_API_KEY = "chv_SRUdL_dd717704a8fe8453ae5452e0bae9b368ae57787bbccd418ba0281ea271ba36acd71a5b0f95fd9bae8763d01b29728ba2cdb2c0ae262008315c91f54fdcb2541b";
    private static final String PICGO_UPLOAD_URL = "https://www.picgo.net/api/1/upload";

    public ImageUploadUtil(TencentCosUtil tencentCosUtil) {
        this.tencentCosUtil = tencentCosUtil;
    }

    /**
     * 上传头像（顺序：PicGo -> Imgbb -> 腾讯OSS）
     */
    public AjaxResult uploadAvatar(MultipartFile file) {
        // 先尝试 picgo 上传
        AjaxResult result = uploadToPicgo(file);
        if (isSuccess(result)) {
            log.info("上传成功，使用 picgo");
            return result;
        }

        // 如果 picgo 失败，尝试 imgbb
        result = uploadToImgbb(file);
        if (isSuccess(result)) {
            log.info("上传成功，使用 imgbb");
            return result;
        }

        // 如果 imgbb 失败，尝试腾讯 OSS
        result = uploadToTencentOSS(file, "movie/avatar/");
        if (isSuccess(result)) {
            log.info("上传成功，使用 tencent oss");
            return result;
        }

        return AjaxResult.error("图片上传失败");
    }

    /**
     * PicGo 上传
     */
    private AjaxResult uploadToPicgo(MultipartFile file) {
        try {
            HttpResponse response = HttpRequest.post(PICGO_UPLOAD_URL)
                    .form("key", PICGO_API_KEY)
                    .form("source", cn.hutool.core.codec.Base64.encode(file.getBytes()))
                    .execute();

            if (response.getStatus() == 200) {
                JSONObject json = JSONUtil.parseObj(response.body());
                int statusCode = json.getInt("status_code", 500);
                if (statusCode == 200) {
                    String url = json.getJSONObject("image").getStr("url");
                    return AjaxResult.success("上传成功", url);
                }
            }
            return AjaxResult.error("Picgo 上传失败: " + response.body());
        } catch (Exception e) {
            return AjaxResult.error("Picgo 上传异常：" + e.getMessage());
        }
    }

    /**
     * Imgbb 上传
     */
    private AjaxResult uploadToImgbb(MultipartFile file) {
        try {
            String base64Image = Base64.getEncoder().encodeToString(file.getBytes());

            HttpResponse response = HttpRequest.post(IMGBB_UPLOAD_URL)
                    .form("key", IMGBB_API_KEY)
                    .form("image", base64Image)
                    .execute();

            if (response.getStatus() == 200) {
                JSONObject json = JSONUtil.parseObj(response.body());
                if (json.getBool("success")) {
                    String url = json.getJSONObject("data").getStr("url");
                    return AjaxResult.success("上传成功", url);
                }
            }
            return AjaxResult.error("Imgbb 上传失败: " + response.body());
        } catch (Exception e) {
            return AjaxResult.error("Imgbb 上传异常：" + e.getMessage());
        }
    }

    /**
     * 腾讯 COS 上传
     */
    private AjaxResult uploadToTencentOSS(MultipartFile file, String path) {
        try {
            String url = tencentCosUtil.upload(file, path);
            return AjaxResult.success("上传成功", url);
        } catch (Exception e) {
            return AjaxResult.error("腾讯OSS 上传异常：" + e.getMessage());
        }
    }

    /**
     * 判断是否上传成功
     */
    private boolean isSuccess(AjaxResult result) {
        Object code = result.get("code");
        return code != null && code.equals(200);
    }
}
